<template>
  <!--  ref= dialog是给flowButton导出按钮获取到弹窗用的-->
  <fks-dialog
    ref="dialog"
    :visible="true"
    :append-to-body="true"
    :fullscreen="isFullScreen"
    :show-close="!isFullScreen"
    :width="dialogWidth"
    top="8vh"
    class="dialog-8vh"
    v-bind="$attrs"
    @close="close"
  >
    <!-- 弹窗标题（icon + 文字） -->
    <template slot="title">
      <!-- 表单新增 -->
      <i
        v-if="type === 'add'"
        class="fks-icon-plus"
      />
      <!-- 表单执行\编辑 -->
      <i
        v-if="type === 'execute' || type === 'edit'"
        class="fks-icon-edit"
      />
      <!-- 表单查看 -->
      <i
        v-if="type === 'view'"
        class="fks-icon-view"
      />
      <span>{{ formName + taskNodeName }}</span>
    </template>
    <component
      :is="dynamicForm"
      ref="formTemp"
      v-bind="$attrs"
      @setFormName="setFormName"
      @setModelKey="setModelKey"
      @setEntityName="setEntityName"
      @setService="setService"
      @setPreSaveValidateProps="setPreSaveValidateProps"
      @setDialogWidth="setDialogWidth"
    />
    <fks-form
      v-if="type != 'view'"
      ref="form"
    >
      <fks-form-item
        v-if="type != 'add'"
        :label="LANG.ADVICE"
        prop="comment"
      >
        <fks-input
          v-model="comment"
          type="textarea"
          :rows="2"
        />
      </fks-form-item>
      <!--      <fks-form-item label v-if="!!notes">-->
      <!--        <div class="form-ps">-->
      <!--          <p v-html="notes"></p>-->
      <!--        </div>-->
      <!--      </fks-form-item>-->
    </fks-form>
    <new-flow-button
      ref="flowButton"
      style="margin-bottom: 0; text-align: center"
      :loading.sync="buttonLoading"
      :comment="comment"
      :form-key="formKey"
      :form-name="formName"
      :task-id="taskId"
      @submit="handleSubmit"
      @onSuccess="onSuccess"
      @preSave="handlePreSave"
      @abandon="handleAbandon"
      @getPdf="getPdf"
    >
      <template slot="after">
        <!--默认有修改按钮,下面的为自定义按钮-->
        <!-- <fks-button type="primary">{{LANG.MODIFY}}</fks-button> -->
      </template>
      <template v-if="customButton.length > 0" slot="after">
        <fks-button
          v-for="(item, index) in customButton"
          :key="index + 'btn'"
          :type="item.type"
          :plain="item.plain"
          :style="item.style"
          @click="item.event"
        >
          {{ item.name }}
        </fks-button>
      </template>
    </new-flow-button>
    <fks-flow-comments
      :flow-active="type !== 'add'"
      :flow-info="flowInfo"
      :data="comments"
      :data-serise="commentSeries"
    />
  </fks-dialog>
</template>

<script>
import Mix from '@/mixins/module'
import NewFlowButton from '@/modules/FormCenter/components/NewFlowButton/NewFlowButton'
import {
  getProcessHistory,
  getHistoryNodes,
  getModelXML,
  getUserTaskDetail,
  processAbandon
} from './api'
import { submitForm } from './api'
import downloadPdf from '@/utils/htmlToPdf'
import emitter from 'fawkes-lib/src/mixins/emitter'

export default {
  name: 'FormCenter',
  componentName: 'FormCenter',
  components: {
    NewFlowButton
  },
  mixins: [Mix, emitter],
  provide() {
    return {
      parentComponent: this
    }
  },
  data() {
    return {
      type: this.$route.params.type,
      formKey: this.$route.params.formKey,
      bizId: this.$route.params.bizId,
      taskId: this.$route.params.taskId,
      taskKey: this.$route.params.taskKey,
      entityName: '',
      formName: '', //表单名称
      service: {}, //提交地址和初始化地址
      dynamicForm: '', // 动态组件
      comment: '', // 流程评论内容
      // 通过路由获取的变量(如果type参数中以oa_开头则表示从老oa跳转的表单使用全屏模式)
      isFullScreen:
        this.$route.params.type.split('_')[0] == 'oa' ? true : false,
      processInstanceId:
        this.$route.params.processInstanceId ||
        this.$route.query.processInstanceId ||
        '', // 流程实例ID
      taskNodeName: '', // 当前任务节点名称
      // 通过子组件getForm传递的变量
      customButton: [], // 自定义按钮数组（根据数组在流程按钮后渲染出对应的按钮）
      // notes: '', // 表单提示部分的html，根据其生成在对应位置
      // 表单提交时或者表单初始化时赋值的变量
      // 表单评论信息
      comments: [],
      commentSeries: {
        taskName: 'taskName',
        userName: 'asignee',
        realName: 'asigneeName',
        solveType: 'approveStateName',
        approveDate: 'approveDate',
        createDate: 'createDate',
        flag: 'approveState',
        comment: 'comment',
        delegateList: 'delegateList'
      },
      flowInfo: {
        xml: '',
        //flow-comment组件不传下面的参数会报forEach的错
        currentNode: [],
        userTask: [],
        exclusiveGateway: []
      },
      flowData: {
        modelKey: ''
      },
      preSaveValidateProps: [], //暂存校验字段
      //上传中的文件列表
      uploadingList: [],
      buttonLoading: false,
      FormDetailValid: true,
      dialogWidth: '960px'
    }
  },

  watch: {
    'flowData.modelKey': {
      handler(val) {
        if (val) {
          this.initProcess()
        }
      }
    },
    'uploadingList.length'(val) {
      this.buttonLoading = val > 0
    }
  },
  mounted() {
    this.initForm()
    //监听form-upload的上传事件
    this.$on('uploading', (fileId) => {
      //上传文件时，将文件id加入到uploadingList中
      this.uploadingList.push(fileId)
    })
    this.$on('uploaded', (fileId) => {
      //上传成功后,将文件id从uploadingList中移除
      const index = this.uploadingList.indexOf(fileId)
      if (index > -1) {
        this.uploadingList.splice(index, 1)
      }
    })
    //监听明细表校验的结果
    this.$on('FormDetailValidate', (valid) => {
      this.FormDetailValid = valid
    })
  },
  methods: {
    useProcess(buttonInfo, variable) {
      let processData = {
        modelKey: this.flowData.modelKey,
        bizId: this.bizId,
        processInstanceId: this.processInstanceId,
        formKey: this.formKey,
        stageFlag: buttonInfo.type === 'saveDraft' ? 1 : 0,
        variable: variable,
        taskId: this.taskId,
        approval: buttonInfo.type === 'saveDraft' ? 'stage' : '',
        comment: this.comment,
        targetKey: buttonInfo.targetKey
      }
      return processData
    },
    async submit(buttonInfo) {
      //派发事件，让明细表校验
      this.broadcast('FormDetail', 'validateForm')
      //明细表校验不通过,直接return
      if (!this.FormDetailValid) {
        return
      }
      this.broadcast('FormUpload', 'setG9s')
      const result = await this.$refs.formTemp.beforeSubmit(buttonInfo)
      //如果beforeSubmit返回了false,就不进行后续操作了
      if (result === false) {
        return
      }
      let variable = result ? result : this.getFormData()
      let submitData = {
        entityName: this.entityName,
        entityObject: variable,
        detailParamList: this.getDetailParamList(),
        formProcessParam: this.useProcess(buttonInfo, variable)
      }
      this.buttonLoading = true
      submitForm(this.service.submit, submitData)
        .then((res) => {
          this.buttonLoading = false
          if (res.status) {
            this.onSuccess(res, 'SUBMIT')
          }
        })
        .catch(() => {
          this.buttonLoading = false
        })
    },
    async handleSubmit(buttonInfo) {
      let valid = false
      try {
        valid = await this.$refs.formTemp.$refs.form.validate()
      } catch (err) {
        valid = false
      }
      if (!valid) {
        return
      }
      this.submit(buttonInfo)
    },
    async handlePreSave(buttonInfo) {
      let valid = true
      if (this.preSaveValidateProps.length > 0) {
        this.$refs.formTemp.$refs.form.validateField(
          this.preSaveValidateProps,
          (err) => {
            err && (valid = false)
          }
        )
      }
      if (!valid) {
        return
      }
      this.submit(buttonInfo)
    },
    handleAbandon() {
      this.$confirm(this.LANG.ABANDON_CONFIRM, {
        title: this.LANG.TIPS,
        type: 'warning',
        confirmButtonText: this.LANG.CONFIRM,
        cancelButtonText: this.LANG.CANCEL,
        confirmButtonClass: 'fks-button--danger',
        deleteMode: true
      }).then(() => {
        const flowData = {
          taskId: this.taskId,
          bizId: this.bizId,
          comment: this.comment,
          formKey: this.formKey
        }
        processAbandon(flowData)
          .then((res) => {
            this.buttonLoading = false
            if (res.status) {
              this.onSuccess(res, 'ABANDON')
            }
          })
          .catch((err) => {
            this.buttonLoading = false
            console.log(err)
          })
      })
    },
    close() {
      if (this.$route.query.back) {
        this.$router.back()
        return false
      }
      if (this.isFullScreen) {
        window.location.href = 'about:blank'
        window.close()
      }
      let path = this.$route.fullPath
      for (path; path.includes('form'); ) {
        path = path.match(/(\S*)\/form/)[1]
      }
      this.$router.replace(path)
      // this.$router.back(-1) // 页面刷新之后回不去
      //派发弹窗关闭事件，使表格能够监听到
      this.$emit('close')
    },
    async onSuccess(res, type) {
      if (res.status) {
        this.$message({
          type: 'success',
          message: (this.LANG[type] || '') + ' ' + this.LANG.SUCCESS,
          showClose: true
        })
      } else {
        this.$message({
          type: 'warning',
          message: (this.LANG[type] || '') + ' ' + this.LANG.FAILED,
          showClose: true
        })
      }
      //如果表单有onSuccess方法，则先执行此方法，如果返回值不===false就关闭弹窗
      if (this.$refs.formTemp.onSuccess) {
        const result = await this.$refs.formTemp.onSuccess(res, type)
        if (result !== false) {
          this.$emit('success', res, type) //派发给表格页面的router-view的success
          this.close()
        }
      } else {
        //没有onSuccess方法则直接关闭弹窗
        this.$emit('success', res, type) //派发给表格页面的router-view的success
        this.close()
      }
    },
    initForm() {
      const reqs = require.context(
        '@/modules/FormCenter',
        true,
        /index\.vue/,
        'lazy'
      )
      reqs.keys().forEach((key) => {
        if (RegExp(`\\/${this.formKey}\\/`).test(key)) {
          // console.log(this.formKey, key)
          reqs(key).then((res) => {
            this.dynamicForm = res.default
          })
        }
      })
    },
    initProcess() {
      //有taskId,获取流程图
      if (this.taskId) {
        // 若有taskId则获取当前任务节点名称
        getUserTaskDetail(this.taskId).then((res) => {
          if (res.status && res.data.taskName) {
            this.taskNodeName = '—' + res.data.taskName
          }
        })
      }
      if (this.type !== 'add') {
        getProcessHistory({ taskId: this.taskId, bizId: this.bizId }).then(
          (res) => {
            this.comments = res.data
          }
        )
      }
      getModelXML({ modelKey: this.flowData.modelKey }).then((res) => {
        this.flowInfo.xml = res.data.bpmnXml
        if (this.bizId) {
          getHistoryNodes({
            // taskId: this.taskId
            bizId: this.bizId
          }).then((resp) => {
            this.flowInfo = Object.assign(this.flowInfo, resp.data)
          })
        }
      })
    },
    setFormName(formName) {
      this.formName = formName
    },
    setModelKey(modelKey) {
      this.flowData.modelKey = modelKey
    },
    setEntityName(entityName) {
      this.entityName = entityName
    },
    setService(service) {
      this.service = service
    },
    setPreSaveValidateProps(props = []) {
      this.preSaveValidateProps = props
    },
    setDialogWidth(width) {
      this.dialogWidth = width
    },
    getPdf() {
      this.buttonLoading = true
      let dom = this.$refs.dialog.$el.getElementsByClassName(
        'fks-dialog__body'
      )[0]
      let title = this.formName
      downloadPdf(dom, title).then(() => {
        this.buttonLoading = false
      })
    },
    getFormData() {
      try {
        return this.$refs.formTemp.$data.formData
      } catch (err) {
        return {}
      }
    },
    //明细表数据
    getDetailParamList() {
      try {
        return this.$refs.formTemp.$data.detailParamList
      } catch (err) {
        return []
      }
    }
  }
}
</script>
<style lang="scss" scoped>
::v-deep .no-flow-chart {
  *[aria-controls*='pane-flow'] {
    display: none;
  }
}
</style>
